import type { App, Directive } from "vue";
import { debounce, throttle } from "lodash-es";

/** 指令参数格式：v-debounce:事件名:延迟  或  v-throttle:事件名:延迟 */
const parseArg = (arg = "click:300") => {
  const [event = "click", time = "300"] = arg.split(":");
  return { event, delay: Number(time) || 300 };
};

/* 防抖指令 */
const debounceDirective: Directive<HTMLElement, (...args: unknown[]) => void> = {
  mounted(el, binding) {
    const { event, delay } = parseArg(binding.arg);
    const handler = debounce(binding.value, delay);
    el._debounceHandler = handler;
    el.addEventListener(event, handler);
  },
  unmounted(el, binding) {
    const { event } = parseArg(binding.arg);
    el.removeEventListener(event, el._debounceHandler!);
    delete el._debounceHandler;
  },
};

/* 节流指令 */
const throttleDirective: Directive<HTMLElement, (...args: unknown[]) => void> = {
  mounted(el, binding) {
    const { event, delay } = parseArg(binding.arg);
    const handler = throttle(binding.value, delay);
    el._throttleHandler = handler;
    el.addEventListener(event, handler);
  },
  unmounted(el, binding) {
    const { event } = parseArg(binding.arg);
    el.removeEventListener(event, el._throttleHandler!);
    delete el._throttleHandler;
  },
};

export function stepCustomDirective(app: App) {
  app.directive("debounce", debounceDirective);
  app.directive("throttle", throttleDirective);
}
